package com.stu.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;


public class JoystickView extends View {

	private Paint ringPaint, stickPaint;
	private Path ringPath;
	private float ringWidth, stickRadius, ringRadius, viewScale;
	private int xPos, yPos;
	
	
	public void setXPos(int v) {
		xPos = v;
	}
	
	public void setYPos(int v) {
		yPos = v;
	}
	
	public JoystickView(Context context) {
		super(context);
		initJoystickView(context);
	} 

	public JoystickView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initJoystickView(context);
	}
	
	public JoystickView(Context context, AttributeSet attrs, int defaultStyle) {
		super(context, attrs, defaultStyle);
		initJoystickView(context);
	}
	

	protected void initJoystickView(Context c) {
		xPos = 50;
		yPos = 50;
		ringWidth = 10;

		ringPaint = new Paint();
		stickPaint = new Paint();
		ringPath = new Path();
		
		ringPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		ringPaint.setColor(Color.BLACK);
		ringPaint.setStrokeWidth(ringWidth);		// strokeWidth is measured from the centerline
		ringPaint.setStyle(Paint.Style.STROKE);
		
		stickPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		stickPaint.setColor(Color.BLUE);
		stickPaint.setStyle(Paint.Style.FILL);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
		// The ring is a circle that fills as much space as possible.
		// Set the measured dimensions by figuring out the shortest boundary,
		// height or width.
		int measuredWidth = measure(widthMeasureSpec);
		int measuredHeight = measure(heightMeasureSpec);
		
		int d = Math.min(measuredWidth, measuredHeight);
		
		setMeasuredDimension(d, d);
	}

	private int measure(int measureSpec) {
		int result = 0; 
	
		// Decode the measurement specifications.
		int specMode = MeasureSpec.getMode(measureSpec);
		int specSize = MeasureSpec.getSize(measureSpec); 
		
		if (specMode == MeasureSpec.UNSPECIFIED) {
			// Return a default size of 200 if no bounds are specified. 
			result = 200;
		} else {
			// As you want to fill the available space
			// always return the full available bounds.
			result = specSize;
		} 
		return result;
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		
		float centerX = w / 2;
		float centerY = h / 2;

		ringRadius = Math.min(centerX, centerY) - (ringWidth / 2);
		// make stick radius 40% of the ring diameter
		stickRadius = (float)0.2 * ringRadius;

		ringPath.reset();
		ringPath.addCircle(centerX, centerY, ringRadius, Path.Direction.CW);
		
		viewScale = ringWidth + (ringRadius * 2) - (stickRadius * 2);
	}

	@Override 
	protected void onDraw(Canvas canvas) {
		canvas.drawPath(ringPath, ringPaint);
		// 0 position is left
		Float scaledX = (float)(xPos / 100.0) * viewScale;
		// 0 position is bottom
		Float scaledY = (float)((100 - yPos) / 100.0) * viewScale;
		canvas.drawCircle(scaledX + stickRadius, scaledY + stickRadius, stickRadius, stickPaint);
	}
} 
